/*
 *
 *  * Copyright (c) iwindplus Technologies Co., Ltd.2024-2030, All rights reserved.
 *
 *
 */

package com.iwindplus.gateway.server.client;

import com.iwindplus.base.domain.constant.CommonConstant.NetWorkConstant;
import com.iwindplus.base.domain.vo.ApiSignVO;
import com.iwindplus.base.domain.vo.ResultVO;
import com.iwindplus.mgt.domain.constant.MgtConstant;
import com.iwindplus.mgt.domain.vo.system.ServerRouteDefinitionVO;
import jakarta.annotation.Resource;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

/**
 * mgt客户端.
 *
 * @author zengdegui
 * @since 2025/08/24 16:18
 */
@Slf4j
@Component
public class MgtClient {

    public static final String MGT_PREFIX = String.format("%s%s", NetWorkConstant.LB_PREFIX, MgtConstant.MGT_SERVER_NAME);

    @Resource
    private WebClient loadBalancedWebClient;

    /**
     * 获取所有路由定义.
     *
     * @return Mono<List < ServerRouteDefinitionVO>>
     */
    public Mono<List<ServerRouteDefinitionVO>> listRouteDefinition() {
        final String url = String.format("%s%s", MGT_PREFIX,
            "/inner/server/listRouteDefinition");

        return loadBalancedWebClient.get()
            .uri(url)
            .retrieve()
            .bodyToMono(new ParameterizedTypeReference<ResultVO<List<ServerRouteDefinitionVO>>>() {
            }).flatMap(ResultVO::unwrap);
    }

    /**
     * 根据accessKey获取api签名信息.
     *
     * @param accessKey accessKey
     * @return Mono<ApiSignVO>
     */
    public Mono<ApiSignVO> getByAccessKey(String accessKey) {
        final String url = String.format("%s%s", MGT_PREFIX,
            "/inner/appCert/getByAccessKey?accessKey={accessKey}");

        return loadBalancedWebClient.get()
            .uri(url, accessKey)
            .retrieve()
            .bodyToMono(new ParameterizedTypeReference<ResultVO<ApiSignVO>>() {
            }).flatMap(ResultVO::unwrap);
    }

    /**
     * 获取所有API.
     *
     * @return Mono<List < String>>
     */
    public Mono<List<String>> listApi() {
        final String url = String.format("%s%s", MGT_PREFIX,
            "/inner/apiWhiteList/listApi");

        return this.getListMono(url);
    }

    /**
     * 获取所有IP.
     *
     * @return Mono<List < String>>
     */
    public Mono<List<String>> listIp() {
        final String url = String.format("%s%s", MGT_PREFIX,
            "/inner/ipBlackList/listIp");

        return this.getListMono(url);
    }

    /**
     * 获取用户API权限.
     *
     * @param orgId  组织主键
     * @param userId 用户主键
     * @return Mono<List < String>>
     */
    public Mono<List<String>> listApiCheckedByUserId(Long orgId, Long userId) {
        final String url = String.format("%s%s", MGT_PREFIX,
            "/inner/resource/listApiCheckedByUserId?orgId={orgId}&userId={userId}");

        return this.getListMono(url, orgId, userId);
    }

    /**
     * 校验用户API权限.
     *
     * @param orgId  组织主键
     * @param userId 用户主键
     * @param path   路径
     * @return Mono<Boolean>
     */
    public Mono<Boolean> checkApiByUserId(Long orgId, Long userId, String path) {
        final String url = String.format("%s%s", MGT_PREFIX,
            "/inner/resource/checkApiByUserId?orgId={orgId}&userId={userId}&path={path}");

        return loadBalancedWebClient.get()
            .uri(url, orgId, userId, path)
            .retrieve()
            .bodyToMono(new ParameterizedTypeReference<ResultVO<Boolean>>() {
            }).flatMap(ResultVO::unwrap);
    }

    private Mono<List<String>> getListMono(String url, Object... uriVariables) {
        return loadBalancedWebClient.get()
            .uri(url, uriVariables)
            .retrieve()
            .bodyToMono(new ParameterizedTypeReference<ResultVO<List<String>>>() {
            }).flatMap(ResultVO::unwrap);
    }

}
